package max.ta.stock.indicator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import max.ta.data.entity.StockQuote;
import max.ta.data.entity.StockValueType;

import org.apache.log4j.Logger;

public abstract class MAIndicator
	extends AbstractIndicator
	implements Indicator {

    private static final Logger logger = Logger.getLogger(MAIndicator.class);
    // ---------------------------------------------------------------------------------------
    private static final Comparator<StockQuote> COMPARATOR = new Comparator<StockQuote>() {

	@Override
	public int compare(StockQuote o1, StockQuote o2) {
	    return o1.getDate().compareTo(o2.getDate());
	}
    };
    // ---------------------------------------------------------------------------------------
    private final int window;

    public MAIndicator(int window) {
	super();
	this.window = window;
    }

    public int getWindowSize() {
	return window;
    }

    @Override
    public List<IndicatorValue> compute(List<StockQuote> quotes, StockValueType type) {
	logger.info(">>>  Compute MA for series size " + quotes.size() + " -  window size :" + window);
	validate(quotes);
	Collections.sort(quotes, COMPARATOR);
	log(quotes);
	List<IndicatorValue> indicators = new ArrayList<IndicatorValue>();
	for (int i = window - 1; i < quotes.size(); i++) {
	    StockQuote q = quotes.get(i);
	    int start = i - window + 1;
	    int end = i + 1;
	    logger.debug(i + " : [" + start + "-" + end + "[");
	    List<StockQuote> previous = quotes.subList(start, end);
	    double ma = computeMA(previous, type);
	    Date date = q.getDate();
	    IndicatorValue v = new IndicatorValue(date, ma);
	    indicators.add(v);
	}
	return indicators;
    }

    public abstract double computeMA(List<StockQuote> previous, StockValueType type);

    private void validate(List<StockQuote> quotes) {
	if (quotes.size() < window) {
	    throw new IllegalArgumentException("Input series size " + quotes.size() + " is less than window size :" + window);
	}
    }

    protected static void log(List<StockQuote> quotes) {
	for (StockQuote q : quotes) {
	    logger.debug(q);
	}
    }
}
